package com.zsr.xmall.auth;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

/**
 * springSession核心原理
 * <a href="https://juejin.cn/post/6844904159091621901">.参考链接..</a>
 * <p>  1)、@EnableRedisHttpSession中导入 RedisHttpSessionConfiguration 配置</p>
 *
 * <p>      1、给容器添加了一个组件 RedisIndexedSessionRepository，【关键组件】作为 Redis 消息订阅的监听器, 因为它实现了 MessageListener 接口。
 * 当 Redis 中 key 过期或销毁时, 会通知将 RedisIndexedSessionRepository 调用其onMessage() 方法来处理消息。
 * 还实现了许多操作 Redis Session 的操作方法，如 save(), findById(), findByIndexNameAndIndexValue(), deleteById() 等。</p>
 *
 * <p>      2、RedisHttpSessionConfiguration 继承于 SpringHttpSessionConfiguration，后者中使用 @PostConstruct 注解初始化CookieSerializer
 * 其中@PostConstruct该注解被用来修饰一个非静态的void方法。被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行，并且只会被服务器执行一次。PostConstruct在构造函数之后执行，init（）方法之前执行。
 * Constructor > @Autowired > @PostConstruct  先执行完构造方法，再注入依赖，最后执行初始化操作，所以这个注解就避免了一些需要在构造方法里使用依赖组件的尴尬。</p>
 *
 * <p>     3、SpringHttpSessionConfiguration 中提供 SessionRepositoryFilter 组件【关键组件】，作为session存储过滤器，每个请求过来都必须经过filter，
 * SessionRepositoryFilter创建时 将步骤1的 sessionRepository 获取到，核心在其中的doFilterInternal() 方法，
 * <b>【将 request 和 response 对象转换成 SessionRepositoryRequestWrapper 和 SessionRepositoryResponseWrapper。】</b>
 * 后续当第一次调用 request 的 getSession() 方法时，会调用到 SessionRepositoryRequestWrapper 的 getSession() 方法。
 * 这个方法的逻辑是先从 request 的属性中查找，如果找不到；再查找一个 key 值是 "SESSION" 的cookie，【DefaultCookieSerializer中默认为SESSION，可修改】
 * 通过这个 cookie 执行getRequestedSession() ==> this.httpSessionIdResolver.resolveSessionIds(this) ==> 最终执行CookieHttpSessionIdResolver.resolveSessionIds() 获取到 sessionId，并通过 SessionRepository 去 redis 中查找，如果查不到，就直接创建一个 RedisSession 对象，同步到 redis 中（同步的时机根据配置来）
 * </p>
 */
@EnableRedisHttpSession     //整合redis作为session存储
@EnableDiscoveryClient
@EnableFeignClients
@SpringBootApplication
public class XmallAuthServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(XmallAuthServerApplication.class, args);
    }

}
